﻿using System.Security.Cryptography;
using System.Text;

namespace Easy.Common.Helper
{
    /// <summary>
    /// CommonHelper
    /// </summary>
    public partial class CommonHelper
    {
        /// <summary>
        /// MD5加密字符串
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static string CalcMD5(string str)
        {
            byte[] bytes = Encoding.UTF8.GetBytes(str);
            return CalcMD5(bytes);
        }

        /// <summary>
        /// MD5加密byte
        /// </summary>
        /// <param name="bytes"></param>
        /// <returns></returns>
        public static string CalcMD5(byte[] bytes)
        {
            using (MD5 md5 = MD5.Create())
            {
                byte[] computeBytes = md5.ComputeHash(bytes);
                StringBuilder sb = new();
                foreach (var item in computeBytes)
                {
                    sb.Append(item.ToString("X").Length == 1 ? "0" + item.ToString("X") : item.ToString("X"));
                }
                return sb.ToString();
            }
        }

        /// <summary>
        /// MD5加密流文件
        /// </summary>
        /// <param name="stream"></param>
        /// <returns></returns>
        public static string CalcMD5(Stream stream)
        {
            using (MD5 md5 = MD5.Create())
            {
                byte[] computeBytes = md5.ComputeHash(stream);
                StringBuilder sb = new ();
                foreach (var item in computeBytes)
                {
                    sb.Append(item.ToString("X").Length == 1 ? "0" + item.ToString("X") : item.ToString("X"));
                }
                return sb.ToString();
            }
        }

        /// <summary>
        /// 生成随机码Chapcha
        /// </summary>
        /// <param name="len"></param>
        /// <returns></returns>
        public static string CreateVerifyCode(int len)
        {
            char[] data = ['a', 'c', 'd', 'e', 'f', 'h', 'k', 'm', 'n', 'r', 's', 't', 'w', 'x', 'y', '@', '!', '#', '$', '%', '^', '&', '*'];
            StringBuilder sb = new ();
            Random rand = new ();
            for (int i = 0; i < len; i++)
            {
                int index = rand.Next(data.Length);//[0,data.length)
                char ch = data[index];
                sb.Append(ch);
            }
            //勤测！
            return sb.ToString();
        }

        /// <summary>
        /// 生成随机码Chapcha
        /// </summary>
        /// <param name="len"></param>
        /// <returns></returns>
        public static string CreateNumberCode(int len)
        {
            char[] data = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'];
            StringBuilder sb = new();
            Random rand = new();
            for (int i = 0; i < len; i++)
            {
                int index = rand.Next(data.Length);//[0,data.length)
                char ch = data[index];
                sb.Append(ch);
            }
            //勤测！
            return sb.ToString();
        }

        #region 获取首字母
        /// <summary>
        /// 在指定的字符串列表CnStr中检索符合拼音索引字符串
        /// </summary>
        /// <param name="cnStr">汉字字符串</param>
        /// <returns>相对应的汉语拼音首字母串</returns>
        public static string GetEnCode(string cnStr, int length)
        {
            StringBuilder sb = new ();
            for (int i = 0; i < length; i++)
            {
                string temp = cnStr.Substring(i, 1);
                string tempReturn = GetSpellCode(temp);
                sb.Append($"{tempReturn}");
            }
            return sb.ToString();
        }

        /// <summary>
        /// 得到一个汉字的拼音第一个字母，如果是一个英文字母则直接返回大写字母
        /// </summary>
        /// <param name="cnChar">单个汉字</param>
        /// <returns>单个大写字母</returns>
        private static string GetSpellCode(string cnChar)
        {
            long iCnChar;
            byte[] arrCN = Encoding.Default.GetBytes(cnChar);

            //如果是字母，则直接返回
            if (arrCN.Length == 1)
            {
                cnChar = cnChar.ToUpper();
            }
            else
            {
                int area = (short)arrCN[0];
                int pos = (short)arrCN[1];
                iCnChar = (area << 8) + pos;

                // iCnChar match the constant
                string letter = "ABCDEFGHJKLMNOPQRSTWXYZ";
                int[] areaCode = [45217, 45253, 45761, 46318, 46826, 47010, 47297, 47614, 48119, 49062, 49324, 49896, 50371, 50614, 50622, 50906, 51387, 51446, 52218, 52698, 52980, 53689, 54481, 55290];
                for (int i = 0; i < 23; i++)
                {
                    if (areaCode[i] <= iCnChar && iCnChar < areaCode[i + 1])
                    {
                        cnChar = letter.Substring(i, 1);
                        break;
                    }
                }
            }
            return cnChar;
        }
        #endregion

        /// <summary>
        /// 使用Guid产生的种子生成真随机数
        /// </summary>
        /// <param name="minNum">最小值(默认0)</param>
        /// <param name="maxNum">最大值(默认999)</param>
        /// <returns></returns>
        public static int GetSingleRandomByGuid(int minNum = 0, int maxNum = 999)
        {
            Random random = new(GetRandomSeedbyGuid());
            return random.Next(minNum, maxNum);
        }

        /// <summary>
        /// 使用Guid产生的种子生成真随机数
        /// </summary>
        /// <param name="minNum">最小值(默认0)</param>
        /// <param name="maxNum">最大值(默认999)</param>
        /// <param name="count">随机数个数(默认99)</param>
        /// <returns></returns>
        public static List<int> GetRandomByGuid(int minNum = 0, int maxNum = 999, int count = 99)
        {
            List<int> list = [];
            Random random = new(GetRandomSeedbyGuid());
            for (int i = 0; i < count; i++)
            {
                list.Add(random.Next(minNum, maxNum));
            }
            return list;
        }

        /// <summary>
        /// 使用Guid生成种子
        /// </summary>
        /// <returns></returns>
        static int GetRandomSeedbyGuid()
        {
            //return new Guid().GetHashCode();
            return Guid.NewGuid().GetHashCode();
        }


        /// <summary>
        /// 获取北京时间
        /// </summary>
        /// <param name="date"></param>
        /// <returns></returns>
        public static DateTime GetBJDate(DateTime date)
        {
            return date.AddHours(8);
        }

    }

}
